import { Body, Controller, Get, Param, Post, UseGuards, Headers } from '@nestjs/common';
import { UserAccountLoginDto, UserAccountPhoneDto, UserAccountWechatDto, UserAccountAppleDto } from './dto/login.dto';
import { LoginService } from './login.service';
import { generateUniqueUserId } from 'src/common/utils/uuid';
import { JwtService } from '@nestjs/jwt';
import { ERROR_CODE, ERROR_MESSAGE, getResponse } from 'src/common/const/const';
import { DiaryService } from 'src/diary/diary.service';
import { AuthService } from 'src/services/Auth';
import { serviceInfoLog, serviceErrorLog } from "src/common/out/logger/access.logger";
import { UserService } from 'src/user/user.service';
import { generateDefaultUserName } from 'src/common/utils/base';

@Controller('account')
export class LoginController {
  constructor(
    private readonly userService: UserService,
    private readonly loginService: LoginService,
    private readonly diaryService: DiaryService,
    private readonly authService: AuthService,
    private readonly jwtService: JwtService,
  ) {
  }

  @Post('/send_verify')
  async login(@Body() userAccountLoginDto: UserAccountLoginDto) {
    let response = await this.loginService.sendVerifyCode(userAccountLoginDto.phone);
    return getResponse(0, "success", response);
  }

  @Post('/phone_verify')
  async phoneLogin(@Body() userAccountPhoneDto: UserAccountPhoneDto) {
    let phoneResponse = await this.loginService.verifyPhoneCode(userAccountPhoneDto.phone, userAccountPhoneDto.code);
    // 手机号验证失败直接返回
    if (!phoneResponse) {
      serviceErrorLog(`phone_verify fail, ${ERROR_MESSAGE[ERROR_CODE.CODE_FAIL]}`)
      return getResponse(ERROR_CODE.CODE_FAIL, ERROR_MESSAGE[ERROR_CODE.CODE_FAIL], {});
    }
    // // 微信小程序验证失败直接返回
    // let wechatMiniProgramResp = await this.loginService.verifyWechatJsCode(userAccountPhoneDto.wechatMiniProgramCode);
    // if (!(wechatMiniProgramResp && wechatMiniProgramResp['unionid'] && wechatMiniProgramResp['openid'])) {
    //   serviceErrorLog(`phone_verify fail, ${ERROR_MESSAGE[ERROR_CODE.WECHAT_MINI_PROGRAM_CODE_FAIL]}`)
    //   return getResponse(ERROR_CODE.WECHAT_MINI_PROGRAM_CODE_FAIL, ERROR_MESSAGE[ERROR_CODE.WECHAT_MINI_PROGRAM_CODE_FAIL], {});
    // }

    const phone = userAccountPhoneDto.phone
    // const wechatCode = wechatMiniProgramResp['openid']
    let userInfo: { phone: string; wechatCode: string; userid: string }

    userInfo = await this.loginService.findUserByPhone(phone)
    // 如果通过 phone 找到了用户
    if (userInfo) {
      // 检查用户 wechatCode 字段是否存在，不存在则绑定 phone 和 wechatCode
      if (!userInfo.wechatCode) {
        // userInfo.wechatCode = wechatCode
        await this.userService.bindWechatCode({ userid: userInfo.userid, wechatCode: userInfo.wechatCode });
      }
      // TODO 如果存在，但是和 wechatCode 不相等
    } else {// 如果通过 phone 没有找到用户
      // userInfo = await this.loginService.findUserByWechatCode(wechatCode)
      // 如果再根据 wechatCode 查找到了用户 ，则绑定 wechatCode 和 Phone
      if (userInfo) {
        userInfo.phone = phone
        await this.userService.bindPhone({ userid: userInfo.userid, phone: userInfo.phone });
      }
    }

    // 如果以上流程都没有找到，则创建新用户
    if (!userInfo) {
      const uniqueUserId = generateUniqueUserId();
      // 创建创建默认用户信息
      let defaultInfo = {
        userid: uniqueUserId,
        avatar: "",
        phone: phone,
        nickName: generateDefaultUserName(),
        wechatCode: "",
        appleCode: "",
      }
      serviceInfoLog(`phone_verify, create user: ${JSON.stringify(userInfo, null, 2)}`)
      this.createNewAccount(defaultInfo);
      userInfo = defaultInfo
    }
    // 在返回用户信息之前，获取虚拟人信息
    userInfo = await this.loginService.findUserWithVirtualCharacter(userInfo);
    
    // 登陆成功获取token
    const token = this.jwtService.sign({ userid: userInfo['userid'] });
    return getResponse(0, "success", { token, userInfo });
  }

  // 微信小程序登录
  @Post('/wechat_mini_program_login')
  async wechatMiniProgramLogin(@Body() userAccountWechatDto: UserAccountWechatDto) {
    // 如果验证成功则获取用户信息
    let userInfo = {};
    let response = await this.loginService.verifyWechatJsCode(userAccountWechatDto.code);
    serviceInfoLog(`wechat_mini_program_login, response of verifyWechatJsCode :${JSON.stringify(response, null, 2)}`)
    if (response && response['unionid'] && response['openid']) {
      const wechatCode = response['openid']
      userInfo = await this.loginService.findUserByWechatCode(wechatCode);
      // 如果用户不存在则创建用户
      if (!userInfo) {
        serviceInfoLog(`wechat_mini_program_login, no user match to wechatCode: ${wechatCode}`)
        const uniqueUserId = generateUniqueUserId();
        // 创建创建默认用户信息
        let defaultInfo = {
          userid: uniqueUserId,
          avatar: "",
          phone: "",
          nickName: generateDefaultUserName(),
          wechatCode: wechatCode,
          appleCode: ""
        }
        this.createNewAccount(defaultInfo);
        userInfo = defaultInfo
        serviceInfoLog(`wechat_mini_program_login, create user: ${JSON.stringify(userInfo, null, 2)}`)
      }
    } else {
      return getResponse(ERROR_CODE.CODE_FAIL, ERROR_MESSAGE[ERROR_CODE.CODE_FAIL], {});
    }
    // 在返回用户信息之前，获取虚拟人信息
    userInfo = await this.loginService.findUserWithVirtualCharacter(userInfo);
    
    const token = this.jwtService.sign({ userid: userInfo['userid'] });
    return getResponse(0, "success", { token, userInfo });
  }

  @Post('/wechat_app_login')
  async weChatAppLogin(@Body() userAccountWechatDto: UserAccountWechatDto) {
    // 如果验证成功则获取用户信息
    let userInfo = {};
    let response = await this.loginService.verifyWechatAppCode(userAccountWechatDto.code);
    serviceInfoLog("[weChatAppLogin the response is] :" + JSON.stringify(response))
    if (response && response['unionid'] && response['openid']) {
      userInfo = await this.loginService.findUserByWechatCode(response['openid']);
      // 如果用户不存在则创建用户
      if (!userInfo) {
        // 默认分配一个唯一用户Id
        const uniqueUserId = generateUniqueUserId();
        // 创建创建默认用户信息
        let defaultInfo = {
          userid: uniqueUserId,
          avatar: "",
          phone: "",
          nickName: generateDefaultUserName(),
          wechatCode: response['openid'],
          appleCode: ""
        }
        this.createNewAccount(defaultInfo);
        userInfo = defaultInfo
      }
    } else {
      return getResponse(ERROR_CODE.CODE_FAIL, ERROR_MESSAGE[ERROR_CODE.CODE_FAIL], {});
    }
    // 在返回用户信息之前，获取虚拟人信息
    userInfo = await this.loginService.findUserWithVirtualCharacter(userInfo);
    
    const token = this.jwtService.sign({ userid: userInfo['userid'] });
    return getResponse(0, "success", { token, userInfo });
  }

  @Post('/apple_login')
  // @Roles('admin')
  async appleLogin(@Body() userAccountAppleDto: UserAccountAppleDto) {
    let response = await this.loginService.verifyAppleCode(userAccountAppleDto.code);
    let result = {
      code: 0,
      data: response,
      msg: "success"
    }
    return result;
  }

  // 退出登陆
  @Post('/loginout')
  async loginout(@Headers() headers: any) {
    return getResponse(0, "success", {});
  }

  // 注销账户
  @Post('/loginoff')
  async loginoff(@Headers() headers: any) {
    const userInfo = this.authService.checkAuth(headers);
    if (!userInfo) {
      return getResponse(ERROR_CODE.VERIFY_EXPIRE, ERROR_MESSAGE[ERROR_CODE.VERIFY_EXPIRE], {})
    }
    const deleteRes = await this.loginService.deleteUser(userInfo.userid);
    if (!deleteRes) {
      return getResponse(ERROR_CODE.INTERNAL_FAIL, ERROR_MESSAGE[ERROR_CODE.INTERNAL_FAIL], {});
    }
    if (deleteRes.affected == 0) {
      return getResponse(ERROR_CODE.INTERNAL_FAIL, ERROR_MESSAGE[ERROR_CODE.INTERNAL_FAIL], {});
    } else {
      return getResponse(0, "success", deleteRes);
    }
  }

  async createNewAccount(defaultInfo: any) {
    const userInfo = await this.loginService.createUser(defaultInfo);
    // 创建完用户默认创建一个日记本
    await this.diaryService.createBill({
      userid: userInfo['userid'],
      diarybillid: "default",
      title: "我的日记本",
      desc: "日常生活",
      showid: "defualt",
      showlogo: "defualt"
    });
  }
}
